package com.yuzhihao.writejvm.constant;

import com.yuzhihao.writejvm.clazz.ClassInfo;
import com.yuzhihao.writejvm.format.PrintFormat;
import com.yuzhihao.writejvm.read.Parse;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.log4j.Log4j2;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;

/**
 *
 * The CONSTANT_Fieldref_info Structure
 *
 * @author yzh
 * @since  2021年11月30日16:36:56
 */

@Data
@Log4j2
@EqualsAndHashCode(callSuper = true)
public class ConstantFieldrefInfo extends ConstantPool{

    private int class_index_u2 = 2;

    private int name_and_type_index_u2 = 2;

    private int class_index;

    private int name_and_type_index;

    private String constant;

    public ConstantFieldrefInfo(Map<String,ConstantPool> pools) {
        super(pools);
        super.name = "Fieldref";
    }

    @Override
    public void parse(DataInputStream dis, ClassInfo ci) {
        try {
            this.class_index = Parse.byteToInt(class_index_u2, dis);
            this.name_and_type_index = Parse.byteToInt(name_and_type_index_u2, dis);
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    @Override
    public String getConstant() {
        if(Objects.nonNull(this.constant)){
            return this.constant;
        }

        ConstantClassInfo cp1 = (ConstantClassInfo) pools.get(String.valueOf(class_index));
        ConstantNameAndTypeInfo cp2 = (ConstantNameAndTypeInfo) pools.get(String.valueOf(name_and_type_index));

        this.constant = cp1.getConstant() + PrintFormat.POINT + cp2.getConstant();

        return constant;
    }

    @Override
    public String print() {
        StringBuilder builder = new StringBuilder();

        builder.append(PrintFormat.MEMPTY).append(PrintFormat.HASHTAG)
                .append(class_index)
                .append(PrintFormat.POINT)
                .append(PrintFormat.HASHTAG)
                .append(name_and_type_index)
                .append(PrintFormat.MEMPTY)
                .append(PrintFormat.DOUBLE_SLASH)
                .append(PrintFormat.EMPTY);

        builder.append(this.getConstant());


        return builder.toString();
    }
}
